use std::fs;
use fern::Dispatch;
use regex::Regex;
use std::fs::OpenOptions;
use std::path::Path;
use std::sync::Arc;
use log::LevelFilter;
use fern::colors::{Color, ColoredLevelConfig};
use chrono::Local;

pub struct LogHandler {
    log_file_path: String,
    log_level: LevelFilter,
}

impl LogHandler {
    pub fn new(log_file_path: &str, log_level: LevelFilter) -> Self {
        Self {
            log_file_path: log_file_path.to_string(),
            log_level,
        }
    }

    pub fn initialize(&self) -> Result<(), fern::InitError> {
        // 正则表达式匹配 ANSI 转义码
        let ansi_escape_re = Arc::new(Regex::new(r"\x1b\[[0-9;]*[a-zA-Z]").unwrap());

        // 获取当前日期并生成日志文件名
        let current_date = Local::now().format("%Y%m%d").to_string();
        let log_file_path_with_date = format!("{}{}.log", self.log_file_path, current_date);

        // 获取日志文件的父目录
        if let Some(parent_dir) = Path::new(&log_file_path_with_date).parent() {
            // 创建父目录及其所有上级目录
            fs::create_dir_all(parent_dir).unwrap();
        }

        // 打开日志文件，配置为追加模式
        let log_file = OpenOptions::new()
            .append(true)
            .create(true)
            .open(&log_file_path_with_date)
            .unwrap();

        // 配置控制台日志输出格式和颜色
        let colored_level_config = ColoredLevelConfig::new()
            .info(Color::Green)
            .debug(Color::Blue)
            .warn(Color::Yellow)
            .error(Color::Red);

        let stdout_dispatcher = Dispatch::new()
            .format(move |out, message, record| {
                let color = colored_level_config.get_color(&record.level());
                let log_message = format!(
                    "{} [{}] {}[{}]{} {}",
                    chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
                    record.target(),
                    format!("\x1b[{}m", color.to_fg_str()),
                    record.level(),
                    "\x1b[0m",
                    message
                );
                out.finish(format_args!("{}", log_message));
            })
            .chain(std::io::stdout());

        let ansi_escape_re_clone = Arc::clone(&ansi_escape_re);
        let file_dispatcher = Dispatch::new()
            .format(move |out, message, record| {
                let log_message = format!(
                    "{} [{}] [{}] {}",
                    chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
                    record.target(),
                    record.level(),
                    message
                );

                // 移除 ANSI 转义码
                let cleaned_message = ansi_escape_re_clone.replace_all(&log_message, "").to_string();

                out.finish(format_args!("{}", cleaned_message));
            })
            .chain(log_file);

        Dispatch::new()
            .level(self.log_level)
            .chain(stdout_dispatcher)
            .chain(file_dispatcher)
            .apply()?;

        Ok(())
    }
}
